package net.bluemind.ysnp.impl;

import java.io.IOException;
import java.nio.ByteBuffer;

import net.bluemind.unixsocket.UnixDomainSocketChannel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * format is : \0 len login \0 len pass \0 len srv \0 len realm
 * 
 * @author tom
 * 
 */
public class SaslauthdProtocol {

	private Logger logger = LoggerFactory.getLogger(getClass());

	private ValidationPolicy vp;

	private static final byte[] SASL_OK = new byte[] { 0, 2, (byte) 'O',
			(byte) 'K' };

	private static final byte[] SASL_FAILED = new byte[] { 0, 2, (byte) 'N',
			(byte) 'O' };

	public SaslauthdProtocol(ValidationPolicy vp) {
		this.vp = vp;
	}

	public void execute(UnixDomainSocketChannel channel) throws IOException {
		ByteBuffer buf = ByteBuffer.wrap(new byte[2028]); // max is 255*4+8
		channel.read(buf);
		byte[] data = buf.array();

		int i = 1;
		String login = new String(data, i + 1, data[i]);

		i += data[i] + 2;
		String password = new String(data, i + 1, data[i]);

		i += data[i] + 2;
		String service = new String(data, i + 1, data[i]);

		i += data[i] + 2;
		String realm = new String(data, i + 1, data[i]);

		if (logger.isDebugEnabled()) {
			logger.debug("login: " + login + " pass: " + password
					+ " service: " + service + " realm: " + realm);
		}

		boolean valid = check(login, password, service, realm);
		ByteBuffer response;
		if (valid) {
			response = ByteBuffer.wrap(SASL_OK);
		} else {
			response = ByteBuffer.wrap(SASL_FAILED);
		}
		channel.write(response);
	}

	private boolean check(String login, String password, String service,
			String realm) {
		return vp.validate(login, password, service, realm);
	}

}
